using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using Microsoft.Practices.EnterpriseLibrary.Logging;

namespace Destra.Common.Logging
{
    public class Logger
    {
        private static string[] GetCategoryArray(Category category)
        {
            List<string> categories = new List<string>();

            foreach (Category categoryValue in Enum.GetValues(typeof(Category)))
            {
                if ((category & categoryValue) == categoryValue)
                {
                    categories.Add(categoryValue.ToString());
                }
            }

            return categories.ToArray();
        }

        private static string GetApplicationName()
        {
            string application = "Unspecified";

            if (ConfigurationManager.AppSettings["LoggingApplicationName"] != null)
            {
                application = ConfigurationManager.AppSettings["LoggingApplicationName"];
            }

            return application;
        }

        public static bool ShouldLog(string application, string[] categories, 
                                     TraceEventType severity, Priority priority, out LogEntry logEntry)
        {
            logEntry = new LogEntry();
            logEntry.AppDomainName = application;
            logEntry.Categories = categories;
            logEntry.Severity = severity;
            logEntry.Priority = (int)priority;

            return Microsoft.Practices.EnterpriseLibrary.Logging.Logger.ShouldLog(logEntry);
        }

        public static bool ShouldLog(string application, Category category,
                                     TraceEventType severity, Priority priority, out LogEntry logEntry)
        {
            return ShouldLog(
                application,
                GetCategoryArray(category),
                severity,
                priority,
                out logEntry);
        }

        public static bool ShouldLog(Category category,
                                     TraceEventType severity, Priority priority, out LogEntry logEntry)
        {
            return ShouldLog(
                GetApplicationName(),
                GetCategoryArray(category),
                severity,
                priority,
                out logEntry);
        }

        public static bool ShouldLog(string[] categories,
                                     TraceEventType severity, Priority priority, out LogEntry logEntry)
        {
            return ShouldLog(
                GetApplicationName(),
                categories,
                severity,
                priority,
                out logEntry);
        }

        public static void Log(LogEntry logEntry)
        {
            Microsoft.Practices.EnterpriseLibrary.Logging.Logger.Write(logEntry);
        }

        public static void Log(string application, string[] categories,
                               TraceEventType severity, Priority priority, string message)
        {
            LogEntry logEntry = new LogEntry();
            logEntry.AppDomainName = application;
            logEntry.Categories = categories;
            logEntry.Severity = severity;
            logEntry.Priority = (int)priority;
            logEntry.Message = message;

            Microsoft.Practices.EnterpriseLibrary.Logging.Logger.Write(logEntry);
        }

        public static void Log(string application, Category category,
                               TraceEventType severity, Priority priority, string message)
        {
            Log(application,
                GetCategoryArray(category),
                severity,
                priority,
                message);
        }

        public static void Log(Category category,
                               TraceEventType severity, Priority priority, string message)
        {
            Log(GetApplicationName(),
                GetCategoryArray(category),
                severity,
                priority,
                message);
        }

        public static void Log(string[] categories,
                               TraceEventType severity, Priority priority, string message)
        {
            Log(GetApplicationName(),
                categories,
                severity,
                priority,
                message);
        }
    }
}